<template>
  <div class="panel-container">
    <div class="panel-header">
      <h3 class="panel-title">桥梁实时监控</h3>
      <div class="panel-actions">
        <el-button-group>
          <el-button size="small" :type="monitorType === 'stress' ? 'primary' : ''" @click="monitorType = 'stress'">应力监测</el-button>
          <el-button size="small" :type="monitorType === 'vibration' ? 'primary' : ''" @click="monitorType = 'vibration'">振动监测</el-button>
          <el-button size="small" :type="monitorType === 'displacement' ? 'primary' : ''" @click="monitorType = 'displacement'">位移监测</el-button>
        </el-button-group>
      </div>
    </div>
    
    <div class="panel-content">
      <div class="bridge-visualization">
        <div class="bridge-image-container">
          <img src="/src/assets/images/xingxingno.png" alt="桥梁结构图" class="bridge-image" />
          
          <!-- 传感器点位标记 -->
          <div 
            v-for="(point, index) in getSensorPoints()" 
            :key="index" 
            :class="['sensor-point', point.status]"
            :style="{
              left: point.x + '%',
              top: point.y + '%'
            }"
            @mouseenter="activePoint = index"
            @mouseleave="activePoint = -1"
          >
            <div v-if="activePoint === index" class="sensor-tooltip">
              <div class="tooltip-header">{{ point.name }}</div>
              <div class="tooltip-content">
                <div class="tooltip-item">
                  <span class="item-label">当前值:</span>
                  <span class="item-value">{{ point.value }} {{ point.unit }}</span>
                </div>
                <div class="tooltip-item">
                  <span class="item-label">状态:</span>
                  <span class="item-value" :class="'status-' + point.status">{{ getStatusText(point.status) }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <div class="monitor-data">
        <div class="data-header">
          <h4 class="data-title">{{ getMonitorTitle() }}</h4>
          <div class="data-time">更新时间: {{ getCurrentTime() }}</div>
        </div>
        
        <div class="data-chart-container" ref="chartContainer"></div>
        
        <div class="data-controls">
          <el-radio-group v-model="timeRange" size="small">
            <el-radio-button label="1h">1小时</el-radio-button>
            <el-radio-button label="6h">6小时</el-radio-button>
            <el-radio-button label="1d">1天</el-radio-button>
            <el-radio-button label="7d">7天</el-radio-button>
          </el-radio-group>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue';
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { TooltipComponent, GridComponent, LegendComponent, ToolboxComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { Monitor, DataAnalysis, Refresh } from '@element-plus/icons-vue';

echarts.use([LineChart, TooltipComponent, GridComponent, LegendComponent, ToolboxComponent, CanvasRenderer]);

// 监控类型
const monitorType = ref('stress');
const timeRange = ref('1h');
const activePoint = ref(-1);

// 图表容器与实例
const chartContainer = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;

// 模拟数据 - 在实际应用中应该从API获取
const sensorData = {
  stress: [
    { id: 1, name: 'S-001', x: 30, y: 45, value: 98.5, unit: 'MPa', status: 'normal' },
    { id: 2, name: 'S-002', x: 50, y: 35, value: 112.7, unit: 'MPa', status: 'warning' },
    { id: 3, name: 'S-003', x: 70, y: 45, value: 87.3, unit: 'MPa', status: 'normal' },
  ],
  vibration: [
    { id: 4, name: 'V-001', x: 25, y: 50, value: 2.3, unit: 'Hz', status: 'normal' },
    { id: 5, name: 'V-002', x: 50, y: 55, value: 3.1, unit: 'Hz', status: 'normal' },
    { id: 6, name: 'V-003', x: 75, y: 50, value: 4.8, unit: 'Hz', status: 'danger' },
  ],
  displacement: [
    { id: 7, name: 'D-001', x: 35, y: 40, value: 5.2, unit: 'mm', status: 'normal' },
    { id: 8, name: 'D-002', x: 55, y: 30, value: 7.8, unit: 'mm', status: 'normal' },
    { id: 9, name: 'D-003', x: 65, y: 40, value: 12.3, unit: 'mm', status: 'warning' },
  ]
};

// 模拟历史数据
const generateHistoricalData = (baseValue: number, count: number) => {
  const now = new Date();
  const result = [];
  
  for (let i = count - 1; i >= 0; i--) {
    const time = new Date(now.getTime() - i * 60 * 60 * 1000);
    const value = baseValue + Math.random() * 10 - 5;
    result.push([time.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }), value.toFixed(1)]);
  }
  
  return result;
};

// 获取监控类型标题
const getMonitorTitle = () => {
  const titles = {
    stress: '桥梁应力监测数据',
    vibration: '桥梁振动监测数据',
    displacement: '桥梁位移监测数据'
  };
  return titles[monitorType.value as keyof typeof titles];
};

// 获取当前时间
const getCurrentTime = () => {
  return new Date().toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  });
};

// 获取当前监控类型的传感器点位
const getSensorPoints = () => {
  return sensorData[monitorType.value as keyof typeof sensorData] || [];
};

// 获取状态文本
const getStatusText = (status: string) => {
  const statusMap: Record<string, string> = {
    normal: '正常',
    warning: '警告',
    danger: '危险'
  };
  return statusMap[status] || '未知';
};

// 初始化图表
const initChart = () => {
  if (!chartContainer.value) return;
  
  // 清除已有实例
  if (chartInstance) {
    chartInstance.dispose();
  }
  
  // 创建新实例
  chartInstance = echarts.init(chartContainer.value);
  updateChart();
  
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize);
};

// 更新图表数据
const updateChart = () => {
  if (!chartInstance) return;
  
  const sensors = getSensorPoints();
  const series = sensors.map(sensor => {
    return {
      name: sensor.name,
      type: 'line',
      smooth: true,
      symbol: 'circle',
      symbolSize: 6,
      data: generateHistoricalData(parseFloat(sensor.value.toString()), 24),
      lineStyle: {
        width: 2
      }
    };
  });
  
  const unit = sensors.length > 0 ? sensors[0].unit : '';
  
  const option = {
    color: ['#409eff', '#67c23a', '#e6a23c', '#f56c6c', '#909399'],
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      }
    },
    legend: {
      data: sensors.map(s => s.name),
      right: 10,
      top: 0
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '40px',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      axisLine: {
        lineStyle: {
          color: '#dcdfe6'
        }
      },
      axisLabel: {
        color: '#606266'
      }
    },
    yAxis: {
      type: 'value',
      name: unit,
      axisLine: {
        show: true,
        lineStyle: {
          color: '#dcdfe6'
        }
      },
      splitLine: {
        lineStyle: {
          color: ['#ebeef5']
        }
      },
      axisLabel: {
        color: '#606266'
      }
    },
    series: series
  };
  
  chartInstance.setOption(option);
};

// 处理窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize();
  }
};

// 监控类型变化时更新图表
watch(monitorType, () => {
  nextTick(() => {
    updateChart();
  });
});

// 时间范围变化时更新图表
watch(timeRange, () => {
  nextTick(() => {
    updateChart();
  });
});

// 组件挂载时初始化图表
onMounted(() => {
  nextTick(() => {
    initChart();
  });
});

// 组件卸载时清理资源
onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
  window.removeEventListener('resize', handleResize);
});
</script>

<style scoped lang="scss">
.panel-container {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.panel-header {
  padding: 16px 20px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  
  .panel-title {
    font-size: 16px;
    font-weight: 600;
    color: #303133;
    margin: 0;
  }
}

.panel-content {
  padding: 20px;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow: hidden;
}

.bridge-visualization {
  position: relative;
  height: 200px;
  background-color: #f8f9fa;
  border-radius: 6px;
  overflow: hidden;
  
  .bridge-image-container {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    
    .bridge-image {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
    
    .sensor-point {
      position: absolute;
      width: 14px;
      height: 14px;
      border-radius: 50%;
      transform: translate(-50%, -50%);
      cursor: pointer;
      box-shadow: 0 0 0 2px white;
      z-index: 2;
      transition: all 0.3s ease;
      
      &::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 6px;
        height: 6px;
        background: inherit;
        border-radius: 50%;
        transform: translate(-50%, -50%);
      }
      
      &:hover {
        transform: translate(-50%, -50%) scale(1.2);
      }
      
      &.normal {
        background-color: #67c23a;
        
        &::before {
          animation: pulse-green 2s infinite;
        }
      }
      
      &.warning {
        background-color: #e6a23c;
        
        &::before {
          animation: pulse-orange 1.5s infinite;
        }
      }
      
      &.danger {
        background-color: #f56c6c;
        
        &::before {
          animation: pulse-red 1s infinite;
        }
      }
      
      &::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 100%;
        height: 100%;
        border-radius: 50%;
        background: inherit;
        opacity: 0.6;
        transform: translate(-50%, -50%) scale(1);
      }
      
      .sensor-tooltip {
        position: absolute;
        bottom: calc(100% + 10px);
        left: 50%;
        transform: translateX(-50%);
        background-color: white;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        border-radius: 4px;
        padding: 0;
        width: 150px;
        z-index: 10;
        
        &::after {
          content: '';
          position: absolute;
          top: 100%;
          left: 50%;
          transform: translateX(-50%);
          border-width: 6px;
          border-style: solid;
          border-color: white transparent transparent transparent;
        }
        
        .tooltip-header {
          background-color: #f5f7fa;
          color: #303133;
          font-weight: 500;
          padding: 8px 12px;
          border-radius: 4px 4px 0 0;
          border-bottom: 1px solid #ebeef5;
        }
        
        .tooltip-content {
          padding: 8px 12px;
          
          .tooltip-item {
            display: flex;
            justify-content: space-between;
            margin-bottom: 4px;
            
            &:last-child {
              margin-bottom: 0;
            }
            
            .item-label {
              color: #909399;
              font-size: 12px;
            }
            
            .item-value {
              font-weight: 500;
              font-size: 12px;
              
              &.status-normal {
                color: #67c23a;
              }
              
              &.status-warning {
                color: #e6a23c;
              }
              
              &.status-danger {
                color: #f56c6c;
              }
            }
          }
        }
      }
    }
  }
}

.monitor-data {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
  min-height: 0;
  
  .data-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    .data-title {
      font-size: 14px;
      font-weight: 600;
      color: #303133;
      margin: 0;
    }
    
    .data-time {
      font-size: 12px;
      color: #909399;
    }
  }
  
  .data-chart-container {
    flex: 1;
    min-height: 220px;
  }
  
  .data-controls {
    display: flex;
    justify-content: center;
    margin-top: auto;
  }
}

@keyframes pulse-green {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.6;
  }
  70% {
    transform: translate(-50%, -50%) scale(2.5);
    opacity: 0;
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}

@keyframes pulse-orange {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.6;
  }
  70% {
    transform: translate(-50%, -50%) scale(2.5);
    opacity: 0;
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}

@keyframes pulse-red {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.6;
  }
  70% {
    transform: translate(-50%, -50%) scale(2.5);
    opacity: 0;
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}
</style> 